home *** CD-ROM | disk | FTP | other *** search
- /*
- File: MiscServices.c
-
- Contains: QuickDraw GX to PostScript conversion code.
- Miscellanious test routines
- PSPrimitiveShape
- PSGetColorSpaceBasis
- Miscellanious shape service routines
-
- Version: Technology: Quickdraw GX 1.1.x
-
- Copyright: © 1990-1997 by Apple Computer, Inc., all rights reserved.
- */
-
- #include "GXToPSBuildConfig.h"
- #include <GXGraphics.h>
- #include "GXGraphicsPriv.h"
- #include "GXToPostScript.h"
- #include "IOUtilities.h"
- #include "RDUtil.h"
- #include "FontHandler.h"
- #include "PublicPostScriptIE.h"
- #include "private.h"
- #include "PSIEResources.h"
- #include "GXErrors.h"
- #include "ShapeUtilities.h"
-
- #ifdef resumeLabel
- #undef resumeLabel
- #endif
- #define resumeLabel(exception)
-
-
-
-
-
-
-
- //<FF>
- /******************************************
- The following routines are for the disposing
- and comparison of graphics objects, allowing for
- the nil case
- *******************************************/
- Boolean PSEqualColorSet(gxColorSet set1, gxColorSet set2)
- {
- if ( (set1 == nil) && (set2 == nil))
- return(true);
- else if (set1 == nil)
- return(false);
- else if (set2 == nil)
- return(false);
- else
- return(GXEqualColorSet(set1, set2));
-
- }//PSEqualColorSet
-
-
- void PSDisposeColorSet(gxColorSet theSet)
- {
- if (theSet != nil)
- GXDisposeColorSet(theSet);
-
- }//PSDisposeColorSet
-
-
- //<FF>
- /********************************************
- The following routines are for the checking
- of equality between objects (styles, inks, and transforms)
- They also check for the equality of any PostScript tags
- which the gx graphics routines wouldn't do
-
- **********************************************/
- Boolean PSEqualInk(gxInk ink1, gxInk ink2)
- {
- long nTags1, nTags2, i;
- gxTag tag1, tag2;
- Boolean result;
-
- result = GXEqualInk(ink1, ink2);
-
- if (result) { // Equal returned true, check tags.
-
- nTags1 = GXGetInkTags(ink1, gxPostScriptTag, 1, gxSelectToEnd, nil);
- nTags2 = GXGetInkTags(ink2, gxPostScriptTag, 1, gxSelectToEnd, nil);
-
- if (nTags1 != nTags2) {
-
- result = false;
-
- } else if (nTags1 != 0) { // If they have the same number of tags (non-zero) compare them
-
- for (i = 1; i <= nTags1; ++i) {
-
- GXGetInkTags(ink1, gxPostScriptTag, i, 1, &tag1);
- GXGetInkTags(ink2, gxPostScriptTag, i, 1, &tag2);
-
- result = GXEqualTag(tag1, tag2);
- if (!result)
- break;
-
- }//end for
-
- }//end if
-
-
- }//end if
-
- return(result);
-
- }//PSEqualInk
-
-
-
- Boolean PSEqualStyle(gxStyle style1, gxStyle style2)
- {
- long nTags1, nTags2, i;
- gxTag tag1, tag2;
- Boolean result;
-
- result = GXEqualStyle(style1, style2);
-
- if (result) { // Equal returned true, check tags.
-
- nTags1 = GXGetStyleTags(style1, gxPostScriptTag, 1, gxSelectToEnd, nil);
- nTags2 = GXGetStyleTags(style2, gxPostScriptTag, 1, gxSelectToEnd, nil);
-
- if (nTags1 != nTags2) {
-
- result = false;
-
- } else if (nTags1 != 0) { // If they have the same number of tags (non-zero) compare them
-
- for (i = 1; i <= nTags1; ++i) {
-
- GXGetStyleTags(style1, gxPostScriptTag, i, 1, &tag1);
- GXGetStyleTags(style2, gxPostScriptTag, i, 1, &tag2);
-
- result = GXEqualTag(tag1, tag2);
- if (!result)
- break;
-
- }//end for
-
- }//end if
-
-
- }//end if
-
- return(result);
-
- }//PSEqualStyle
-
-
-
- Boolean PSEqualTransform(gxTransform transform1, gxTransform transform2)
- {
- long nTags1, nTags2, i;
- gxTag tag1, tag2;
- Boolean result;
-
- //dprintf(trace, "%X vs. %X", transform1, transform2);
-
- result = GXEqualTransform(transform1, transform2);
-
- if (result) { // Equal returned true, check tags.
-
- nTags1 = GXGetTransformTags(transform1, gxPostScriptTag, 1, gxSelectToEnd, nil);
- nTags2 = GXGetTransformTags(transform2, gxPostScriptTag, 1, gxSelectToEnd, nil);
-
- if (nTags1 != nTags2) {
-
- result = false;
-
- } else if (nTags1 != 0) { // If they have the same number of tags (non-zero) compare them
-
- for (i = 1; i <= nTags1; ++i) {
-
- GXGetTransformTags(transform1, gxPostScriptTag, i, 1, &tag1);
- GXGetTransformTags(transform2, gxPostScriptTag, i, 1, &tag2);
-
- result = GXEqualTag(tag1, tag2);
- if (!result)
- break;
-
- }//end for
-
- }//end if
-
-
- }//end if
-
- return(result);
-
- }//PSEqualTransform
-
-
-
-
-
- //<FF>
- /******************
-
- misc test routines
-
- TestInkModeCopy
- TestInkModeOr
- TestMappingPerspective
- TestMappingIdentity
- TestMappingEqual
- TestShapeSquare
- TestShapeOval
- TestStyleDash
-
- ******************/
-
- #ifdef needTestShapeSquare
- /***********************************
- TestShapeSquare:
-
- Is the shape a Square.
-
- If it is, return the width and center.
- If it is not, the width and center are left untouched.
-
- ************************************/
- Boolean TestShapeSquare(gxShape theShape, fixed *width, point *center)
- {
- Boolean isSquare = false;
- rectangle aRect;
- register fixed theWidth, theHeight;
-
- if ( GetShapeType(theShape) == rectangleType ) {
-
- GetRectangle(theShape, &aRect);
- theHeight = aRect.bottom - aRect.top;
- theWidth = aRect.right - aRect.left;
-
- if (theWidth == theHeight) {
-
- isSquare = true;
- *width = theWidth;
- center->x = aRect.left + (theWidth >> 1);
- center->y = aRect.top + (theHeight >> 1);
-
- }//end if
-
- }//end if
-
- return(isSquare);
-
- }//TestShapeSquare;
-
- #endif
-
-
-
- //<FF>
- /******************************
- TestStyleDash:
-
- Returns true if the style contains a dash shape
- or a dash synonym.
-
- *******************************/
- Boolean TestStyleDash(gxStyle theStyle)
- {
- if (GXGetStyleTags(theStyle, gxDashSynonymTag, 1, 1, nil))
- return(true);
- else
- return ( DoesStyleHaveDash(theStyle) );
-
- }//TestStyleDash
-
- //<FF>
- /******************************
- TestStylePattern:
-
- Returns true if the style contains a pattern shape
-
- *******************************/
- Boolean TestStylePattern(gxStyle theStyle)
- {
- return ( DoesStyleHavePattern(theStyle) );
-
- }//TestStylePattern
-
-
-
- /**************
- Routine checks for or-mode
- based on tag. The transfer mode
- resolver is supposed to tag or-mode
- inks so we don't have to do the
- work over again
- ***************/
- short TestInkModeOr( gxInk shInk )
- {
- short mode = 0; // copy mode.
- gxTag orTag;
- long size;
-
- if (GXGetInkTags(shInk, ormd, 1, gxSelectToEnd, nil)) {
-
- GXGetInkTags(shInk, ormd, 1, 1, &orTag);
- GXLockTag(orTag);
- mode = *(short*)GXGetTagStructure(orTag, &size); // Get the transfer mode value.
- GXUnlockTag(orTag);
-
- if ((size == 0) || (mode > 7)) // Avoid PostScript error.
- mode = 0;
-
- /*****
- Tag is 1: SrcOr, 3: SrcBic, 5: NotSrcOr, 7: NotSrcBic
- Convert to:
- 1: SrcOr, 2: SrcBic, 3: NotSrcOr, 4: NotSrcBic
- *****/
-
- mode = (mode >> 1) + 1;
-
- }//end if
-
- return(mode);
-
- }//TestInkModeOr
-
-
-
-
-
-
- Boolean TestMappingEqual( gxMapping *oneMapping, gxMapping *twoMapping )
- {
- long indx = ( sizeof( gxMapping ) >> 2 );
-
- register short i;
-
-
- register Fixed *onePtr = &(oneMapping->map[0][0]);
- register Fixed *twoPtr = &(twoMapping->map[0][0]);
-
- for (i = 8; i >= 0; --i)
- if (*onePtr++ != *twoPtr++)
- break;
-
- return( i < 0 );
- }
-
-
- Boolean TestMappingPerspective( gxMapping *theMapping)
- {
- /* If the mapping has anything other than 0 0 X in the last column, it is a perspective */
-
- return (
- (theMapping->map[0][2] != 0 ) ||
- (theMapping->map[1][2] != 0 )
- );
-
- }//TestMappingForPerspective
-
-
- Boolean TestMappingIdentity( gxMapping *theMapping)
- {
- register Fixed *mapElement;
-
- mapElement = &(theMapping->map[0][0]);
-
- /** Note, this expression depends on evaluation in left-right order **/
-
- return( (*mapElement++ == ff(1)) &&
- (*mapElement++ == ff(0)) &&
- (*mapElement++ == ff(0)) &&
-
- (*mapElement++ == ff(0)) &&
- (*mapElement++ == ff(1)) &&
- (*mapElement++ == ff(0)) &&
-
- (*mapElement++ == ff(0)) &&
- (*mapElement++ == ff(0)) &&
- (*mapElement == fract1)
- );
- }
-
-
-
- void DoNothingNoticeFunction( gxGraphicsNotice theNotice )
- {
- #pragma unused( theNotice )
- }
-
-
-
- //<FF>
- /**********************************
- Routine: ResetShapeStyle:
-
- sets a shape's style to be the default style.
-
- ***********************************/
- void ResetShapeStyle(gxShape theShape)
- {
- gxStyle theStyle, aStyle;
-
- theStyle = GXGetShapeStyle(theShape);
- if (GXGetStyleOwners(theStyle) == 1) {
-
- GXResetStyle(theStyle);
-
- } else {
-
- aStyle = GXNewStyle();
- GXResetStyle(aStyle);
- GXSetShapeStyle(theShape, aStyle);
- GXDisposeStyle(aStyle);
-
- }//end if
-
- }//ResetShapeStyle
-
-
- //<FF>
- /**********************************
- Routine: ResetShapeTransform:
-
- sets a shape's style to be the default style.
-
- ***********************************/
- void ResetShapeTransform(gxShape theShape)
- {
- gxTransform theTransform, aTransform;
-
- theTransform = GXGetShapeTransform(theShape);
- if (GXGetTransformOwners(theTransform) == 1) {
-
- GXResetTransform(theTransform);
-
- } else {
-
- aTransform = GXNewTransform();
- GXResetTransform(aTransform);
- GXSetShapeTransform(theShape, aTransform);
- GXDisposeTransform(aTransform);
-
- }//end if
-
- }//ResetShapeTransform
-
-
-
- //<FF>
- /**************************
- PSPrimitiveShape:
-
- Calls PrimitiveShape but selectively applies
- style attributes instead of all style attributes.
-
- ***************************/
- OSErr PSPrimitiveShape(gxShape theShape, TIEPrimitiveFlags flags)
- {
- gxPatternRecord thePattern;
- gxDashRecord theDash;
- gxJoinRecord theJoin;
- gxCapRecord theCaps;
- Fixed penSize;
-
- /** Remove style attributes we don't want PrimitiveShape to apply **/
-
- if (!(flags & eApplyDash)) {
-
- GXGetShapeDash(theShape, &theDash);
- GXSetShapeDash(theShape, nil);
-
- }//end if
-
- if (!(flags & eApplyPattern)) {
-
- GXGetShapePattern(theShape, &thePattern);
- GXSetShapePattern(theShape, nil);
-
- }//end if
-
- if (!(flags & eApplyJoin)) {
-
- GXGetShapeJoin(theShape, &theJoin);
- GXSetShapeJoin(theShape, nil);
-
- }//end if
-
- if (!(flags & eApplyCaps)) {
-
- GXGetShapeCap(theShape, &theCaps);
- GXSetShapeCap(theShape, nil);
-
- }//end if
-
-
- if (!(flags & eApplyPen)) {
-
- penSize = GXGetShapePen(theShape);
- GXSetShapePen(theShape, 0);
-
- }//end if
-
-
-
-
- /** Do it! **/
- GXPrimitiveShape(theShape);
-
- /** Now put back any style attributes we didn't apply **/
-
- if (!(flags & eApplyDash)) {
-
- if (theDash.dash != nil) {
- GXSetShapeDash(theShape, &theDash);
- GXDisposeShape(theDash.dash);
- }//end if
-
- } else {
-
- GXSetShapeDash(theShape, nil);
-
- }//end if
-
-
- if (!(flags & eApplyPattern)) {
-
- if (thePattern.pattern != nil) {
- GXSetShapePattern(theShape, &thePattern);
- GXDisposeShape(thePattern.pattern);
- }//end if
-
- } else {
-
- GXSetShapePattern(theShape, nil);
-
- }//end if
-
-
- if (!(flags & eApplyJoin)) {
-
- GXSetShapeJoin(theShape, &theJoin);
- if (theJoin.join != nil)
- GXDisposeShape(theJoin.join);
-
- } else {
-
- GXSetShapeJoin(theShape, nil);
-
- }//end if
-
-
- if (!(flags & eApplyCaps)) {
-
- GXSetShapeCap(theShape, &theCaps);
-
- if (theCaps.startCap != nil)
- GXDisposeShape(theCaps.startCap);
-
- if (theCaps.endCap != nil)
- GXDisposeShape(theCaps.endCap);
-
- }//end if
-
-
- if (!(flags & eApplyPen)) {
-
- GXSetShapePen(theShape, penSize);
-
- } else {
-
- /*************************************
- Make the shape hairline becuase if
- we primitivized a frame shape that
- was capped or dashed or joined with
- a framed shape, then the PrimitiveShape
- would add the hairline contours of the
- dash, cap, or join. When drawn they
- must stay hairlines so the parent shape
- must be hairline
- **************************************/
- GXSetShapePen(theShape, 0);
-
- }//end if
-
-
- return(GXGetGraphicsError(nil));
-
- }//PSPrimitiveShape
-
-
- //<FF>
- /******************************************
-
- Routine: ConcatTransform
-
- Routine concatenates two transforms.
-
- Combines the source's mapping and clip with the operand.
-
- Make a transfrom such that a shape drawn through it
- produces the same result as drawing a picture with sourc transform
- containing shape with operand trasnsform.
-
- *******************************************/
- void ConcatTransform(gxTransform source, gxTransform operand)
- {
- gxMapping sourceMapping, operandMapping, combinedMapping, invertedeMapping;
- gxShape sourceClip, operandClip;
-
- /* Get transform data */
-
- GXGetTransformMapping(source, &sourceMapping);
- sourceClip = GXGetTransformClip(source);
-
- GXGetTransformMapping(operand, &operandMapping);
- operandClip = GXGetTransformClip(operand);
-
- /* Concatenate the two mappings */
-
- CopyToMapping(&combinedMapping, &operandMapping);
- MapMapping( &combinedMapping, &sourceMapping);
-
- /* Map the operand clip through the operand mapping, puts clip in source mapping space */
-
- GXSetShapeAttributes(operandClip, GXGetShapeAttributes(operandClip) & ~gxMapTransformShape);
- GXMapShape(operandClip, &operandMapping);
-
- /* Combine the oprand mapped oprand clip with the source clip */
-
- IntersectShapeAndBitmap(sourceClip, operandClip);
-
- /* Combined clip is in sourceMapping space, Put it into space of combined mapping */
-
- InvertMapping(&invertedeMapping, &operandMapping);
- GXMapShape(sourceClip, &invertedeMapping);
-
- /* Make the source transform */
-
- GXSetTransformMapping(source, &combinedMapping);
- GXSetTransformClip(source, sourceClip);
-
- /* clean up */
-
- GXDisposeShape(sourceClip);
- GXDisposeShape(operandClip);
-
-
- }//ConcatTransforms
-
- //<FF>
- /******************************************
- Routine MapWholeShape:
-
- Routine does what MapShape does, except that
- it forces mapping of geometries, handles extra
- clip generated by mapping bitmaps, and also maps
- the shape's clip and style through the mapping
-
- The shape that results from this will have an identity
- mapping and drawing it should produce the same result
- as having drawn the shape with the provided mapping.
-
- Since this routine affects the geometry of a shape,
- any PostScript synonyms will be tossed.
-
- pass nil for mappingToUse to use shape's own mapping.
-
- *******************************************/
- OSErr MapWholeShape(gxShape theShape, gxMapping *mappingToUse)
- {
- gxShape clipShape;
- gxMapping shapesMapping;
- gxMapping *theMapping;
-
- if (mappingToUse == nil) {
-
- GXGetShapeMapping(theShape, &shapesMapping);
- theMapping = &shapesMapping;
-
- } else {
-
- theMapping = mappingToUse;
-
- }//end if
-
- /* Map the clip through the mapping */
-
- clipShape = GXGetShapeClip(theShape);
- GXSetShapeAttributes(clipShape, GXGetShapeAttributes(clipShape) & ~gxMapTransformShape);
- GXMapShape(clipShape, theMapping);
-
- /** Now call make the shape primitive so that all style geometries are also mapped **/
-
- GXPrimitiveShape(theShape);
- ResetShapeStyle(theShape);
-
- /* Let MapShape think there is no clip, I don't know what it might do with it for bitmaps */
-
- GXSetShapeClip(theShape, nil);
-
- GXSetShapeAttributes(theShape, GXGetShapeAttributes(theShape) & ~gxMapTransformShape);
-
- #ifdef printBounds
- if ( GXGetShapeType(theShape) == gxBitmapType ) {
-
- gxPoint points[2];
- gxBitmap theBits;
-
- dprintf(trace, "About to map bitmap shape through:\n%M", theMapping);
- GXGetBitmap(theShape, &theBits, &points[0]);
- points[1].x = points[0].x + ff(theBits.width - 1);
- points[1].y = points[0].y + ff(theBits.height - 1);
-
- dprintf(trace, "Old bounds: %F %F %F %F", points[0].x, points[0].y, points[1].x, points[1].y);
- MapPoints(theMapping, 2, points);
- dprintf(trace, "New bounds: %F %F %F %F", points[0].x, points[0].y, points[1].x, points[1].y);
-
- }//end if
- #endif
-
- GXMapShape(theShape, theMapping);
-
- /* If the shape was a bitmap, MapShape may have added a clip, get it. */
-
- if (GXGetShapeType(theShape) == gxBitmapType) {
-
- gxShape newClip = GXGetShapeClip(theShape); // Get clip generated by MapShape
-
- GXIntersectShape(clipShape, newClip); // and intersect it with old clip.
- GXDisposeShape(newClip);
-
- }//end if
-
- ResetShapeTransform(theShape); // Give the shape the identity transform
- GXSetShapeClip(theShape, clipShape); // Give the shape the mapped clip.
-
- GXDisposeShape(clipShape);
-
-
- /** Now dispose of any PostScript synonyms **/
-
- GXSetShapeTags(theShape, gxPostScriptTag, 1, gxSelectToEnd, 0, nil);
- GXSetShapeTags(theShape, gxPostControlTag, 1, gxSelectToEnd, 0, nil);
-
- return( GXGetGraphicsError(nil) );
-
- }//MapWholeShape
-
-
-
-
-
-
- //<FF>
- /***********************************
- DoFillKey:
-
- Routine outputs the correct PostScript
- Fill key for the gx graphic fill type
-
- *************************************/
- OSErr DoFillKey(TRDParams* pRDParams, gxShapeFill theFill)
- {
- OSErr status;
-
- pRDParams->resIndex = kFillKey;
-
- switch (theFill) {
-
- case gxEvenOddFill:
- status = RDResPrintf(pRDParams, kEvenOddFillKey);
- break;
-
- case gxFrameFill:
- case gxClosedFrameFill:
- status = RDResPrintf(pRDParams, kFrameFillKey);
- break;
-
- case gxWindingFill:
- status = RDResPrintf(pRDParams, kWindingFillKey);
- break;
-
- case gxInverseFill:
- status = RDResPrintf(pRDParams, kInverseFillKey);
- break;
-
- case gxNoFill:
- status = RDResPrintf(pRDParams, kNoFillKey);
- break;
-
- default:
- status = noErr;
- break;
-
- }//end switch(theFill)
-
- ncheck(status);
-
- return(status);
-
- }//DoFillKey
-
- //<FF>
- /*********************************
- DoBeginProcedure:
-
- Routine outputs the Proper PostScript
- for beginning a procedure definition
-
- **********************************/
- OSErr DoBeginProcedure(TIEGlobalsHdl hGlobals)
- {
- OSErr status;
- unsigned char OpenCurlyBrace = '{';
-
- status = PSIEBufferData(hGlobals, &OpenCurlyBrace, 1, gxNoBufferOptions);
- ncheck(status);
-
- return(status);
-
- }//DoBeginProcedure
-
-
- //<FF>
- /*********************************
- DoEndProcedure:
-
- Routine outputs the Proper PostScript
- for ending a procedure definition
-
- **********************************/
- OSErr DoEndProcedure(TIEGlobalsHdl hGlobals)
- {
- OSErr status;
- unsigned char CloseCurlyBrace = '}';
-
- status = PSIEBufferData(hGlobals, &CloseCurlyBrace, 1, gxNoBufferOptions);
- ncheck(status);
-
- return(status);
-
- }//DoEndProcedure
-
-
- //<FF>
- /*********************************
- DoBeginArray:
-
- Routine outputs the Proper PostScript
- for beginning an array definition
-
- **********************************/
- OSErr DoBeginArray(TIEGlobalsHdl hGlobals)
- {
- OSErr status;
- unsigned char beginArray[] = "[\n";
-
- status = PSIEBufferData(hGlobals, beginArray, 2, gxNoBufferOptions);
- ncheck(status);
-
- return(status);
-
- }//DoBeginArray
-
-
- //<FF>
- /*********************************
- DoEndArray:
-
- Routine outputs the Proper PostScript
- for ending an array definition
-
- **********************************/
- OSErr DoEndArray(TIEGlobalsHdl hGlobals)
- {
- OSErr status;
- unsigned char endArray[] = "]\n";
-
- status = PSIEBufferData(hGlobals, endArray, 2, gxNoBufferOptions);
- ncheck(status);
-
- return(status);
-
- }//DoEndArray
-
-
-
-
-
- //<FF>
- /*************************************
- DoNull:
-
- Routine outputs a PostScript null object
-
- **************************************/
- OSErr DoNull(TRDParams *rdParams)
- {
- OSErr status;
-
- rdParams->resIndex = kDoNull;
- status = RDResPrintf(rdParams);
- ncheck(status);
-
- return(status);
-
- }//DoNull;
-
-
-
- //<FF>
- /*****************************************
- BeginProcSetDict:
-
- Routine puts dictioanary containing our procset
- on top of dictionary stack
-
- ******************************************/
- OSErr BeginProcSetDict(TRDParams *rdParams)
- {
- OSErr status;
-
- rdParams->resIndex = kOurDictOnStack;
- status = RDResPrintf(rdParams);
- ncheck(status);
-
- return(status);
-
- }//BeginProcSetDict
-
- /*****************************************
- EndProcSetDict:
-
- Routine removes dictioanary containing our procset
- from top of dictionary stack
-
- ******************************************/
- OSErr EndProcSetDict(TRDParams *rdParams)
- {
- OSErr status;
-
- rdParams->resIndex = kOurDictOffStack;
- status = RDResPrintf(rdParams);
- ncheck(status);
-
- return(status);
-
- }//EndProcSetDict
-
-
- //<FF>
- /*****************************************
- GetPSFrameValue:
-
- Gets the frame value for the SetFrame procedure.
-
- 0: center-framed
- 1: inside-framed
- -1: outside-framed
-
- *******************************************/
- long GetPSFrameValue(gxStyleAttribute theAttributes)
- {
- if (theAttributes & gxInsideFrameStyle)
- return(1);
- else if (theAttributes & gxOutsideFrameStyle)
- return(-1);
- else
- return(0);
-
- }//GetPSFrameValue
-
-
- //<FF>
- /********************************************
- MakeShapeDict:
-
- Make a shape dictionary, leave it on operand stack
-
- hIEGlobals: the globals handle.
- theShape: Shape to make dictionary out of.
- theOptions: requested options (not including makeProcedure, just clip/break, etc…)
-
- *********************************************/
- OSErr MakeShapeDict(TIEGlobalsHdl hIEGlobals, gxShape theShape, TgeometryOptions theOptions)
- {
- OSErr status;
- TIEGlobalsPtr pGlobals;
- TRDParams *pRDParams;
- gxRectangle shapeBounds;
- gxShapeFill theFill;
- gxShapeType theType;
- fhFont currFont; // Save the font info in our globals state.
- gxStyle currTextStyle;
- Fixed currSize;
- long fontChild;
- gxPoint currTangent;
- long currStateFlags;
- char shapeTypeChar;
-
- pGlobals = *hIEGlobals;
- pRDParams = pGlobals->pRDParams;
-
- /***************
- Save the font portion of the graphics state.
- If the shape to be dictionaryized is text/glyph/layout
- then the dictionary will need to contain font-info,
- we do not want the storage of this font info
- in the geometry procedure of the dictionary to
- muck with what we think the graphics state is.
- *****************/
- currStateFlags = pGlobals->ieStateFlags;
- pGlobals->ieStateFlags |= eFontOutOfDate; // force TextStylePrimitive to set font info.
- currFont = pGlobals->theFont;
- fontChild = pGlobals->fontChild;
- currSize = pGlobals->fontSize;
- currTangent = pGlobals->fontTangent;
- currTextStyle = pGlobals->textStyle;
- pGlobals->textStyle = nil; // We stole the style from the gloabals, forcing output of a face
-
-
- /** Output the geometry procedure onto the operand stack **/
-
- nrequire(status = GeometryDrone(hIEGlobals, theShape, theOptions | eMakeProcedure, nil, 0), failed_Output);
-
-
- /** Output the fill key onto the operand stack **/
-
- theType = GXGetShapeType(theShape);
- if ( (theType == gxBitmapType) || (theType == gxTextType) || (theType == gxGlyphType) )
- theFill = gxNoFill; // PostScript proc recognizes this as a geometry that paints itself
- else
- theFill = GXGetShapeFill(theShape);
-
- status = DoFillKey(pRDParams, theFill);
- nrequire(status, failed_Output);
-
- /** Get the bounding box **/
-
- GXGetShapeBounds(theShape, 0, &shapeBounds);
-
- /** Get the character for the shape type **/
- switch(theType) {
-
- case gxRectangleType:
- case gxLineType:
- case gxPointType:
- case gxCurveType:
- case gxPolygonType:
- case gxPathType:
- case gxFullType:
- case gxEmptyType:
- shapeTypeChar = 'g'; // geometric shape
- break;
-
- case gxTextType:
- case gxLayoutType:
- case gxGlyphType:
- shapeTypeChar = 't'; // text shape
- break;
-
- case gxBitmapType:
- {
- gxBitmap theBits;
- GXGetBitmap(theShape, &theBits, nil);
- if (theBits.pixelSize == 1)
- shapeTypeChar = 'b'; // 1 bit bitmap
- else
- shapeTypeChar = 'i'; // deep bitmap.
- }
- break;
-
- default:
- nrequire(status = illegal_type_for_shape, failed_Output);
-
-
- }//end switch
-
- /******
- Make the shape dictionary, leave it on the operand stack
- ******/
-
- pRDParams->resIndex = kMakeShapeDict;
- status = RDResPrintf(pRDParams, shapeBounds.left, shapeBounds.top,
- shapeBounds.right, shapeBounds.bottom, &shapeTypeChar, 1);
- nrequire(status, failed_Output);
-
- status = GXGetGraphicsError(nil);
- ncheck(status);
-
-
- /** Restore the font portion of the graphics state **/
- pGlobals = *hIEGlobals;
- pGlobals->ieStateFlags = currStateFlags;
- pGlobals->theFont = currFont;
- pGlobals->fontChild = fontChild;
- pGlobals->fontSize = currSize;
- pGlobals->fontTangent = currTangent;
- if (pGlobals->textStyle != nil) // If creating the dict used a text style, get rid of it.
- GXDisposeStyle(pGlobals->textStyle);
- pGlobals->textStyle = currTextStyle; // And put back the one we stole.
-
-
- failed_Output:
-
- return(status);
-
- }//MakeShapeDict
-
-
-
- //<FF>
- /***********************************
-
- Routine: DupShapeIfNecessary
-
- This routine is called before any modifications
- are made to a shape to facilitate PostScriptableization.
- The routine will duplicate a shape if its owner count is
- greater than one and return the new reference in the shape's
- place. It is up to the client to dispose of the shape
- if it was duplicated. The client determines that a new
- shape was created by comparing the input and output shape values
-
-
- theShape: The shape that is to be modified.
- shapeCopy: The new shape. (will be eqaul to theShape if no
- duplicate was made.)
-
- ***************************************/
- OSErr DupShapeIfNecessary(gxShape theShape, gxShape* shapeCopy)
- {
- if (GXGetShapeOwners(theShape) > 1)
- *shapeCopy = GXCopyToShape(nil, theShape);
- else
- *shapeCopy = theShape;
-
- return(GXGetGraphicsError(nil));
-
- }//DupShapeIfNecessary
-
-
-
- //<FF>
- /**************************************
-
- Routine OutputTag:
-
- Routine buffers the data in a tag.
- Used for synonyms.
-
- ***************************************/
- OSErr OutputTag(TIEGlobalsHdl hGlobals, gxTag theTag)
- {
- char* data;
- long tagSize;
- OSErr status;
-
- GXLockTag(theTag);
-
- data = ((char*)GXGetTagStructure(theTag, &tagSize) - tagStructureBugOffset);
-
- status = (*hGlobals)->psDevice->BufferData(data, tagSize, gxNoBufferOptions);
-
- GXUnlockTag(theTag);
-
- ncheck(status);
-
-
- return(status);
-
- }//OutputTag
-
-
-
- /****************************************
-
- DoMoveto:
- Routine outputs a moveto for the specified point
-
- rdParams: The RD parameter block.
- thePoint: The point to move to.
-
- ******************************************/
- OSErr DoMoveto(TRDParams *rdParams, gxPoint *thePoint)
- {
- OSErr status;
-
- rdParams->resIndex = kMoveto;
- status = RDResPrintf(rdParams, thePoint);
- ncheck(status);
- return(status);
-
- }//DoMoveto
-
- /****************************************
-
- DoRmoveto:
- Routine outputs a rmoveto for the specified point
-
- rdParams: The RD parameter block.
- thePoint: The point to rmove to.
-
- ******************************************/
- OSErr DoRmoveto(TRDParams *rdParams, gxPoint *thePoint)
- {
- OSErr status;
-
- rdParams->resIndex = kRmoveto;
- status = RDResPrintf(rdParams, thePoint);
- ncheck(status);
- return(status);
-
- }//DoRmoveto
-
-
- /****************************************
-
- DoPoint:
- Routine outputs a point
-
- rdParams: The RD parameter block.
- thePoint: The point
-
- ******************************************/
- OSErr DoPoint(TRDParams *rdParams, gxPoint *thePoint)
- {
- OSErr status;
-
- rdParams->resIndex = kDoPoint;
- status = RDResPrintf(rdParams, thePoint);
- ncheck(status);
- return(status);
-
- }//DoPoint
-
-
-
-
-
- //<FF>
- /*************************
- SkiaMiterToPS:
-
- function converts a skia miter limit value
- to a PostScript miter limit value.
-
- ***************************/
- Fixed SkiaMiterToPS(Fixed miterValue, Fixed lineWidth)
- {
- Fixed adjustValue;
-
- adjustValue = FixedMultiply(lineWidth, Magnitude(fixed1, miterValue << 1));
-
- if (adjustValue < fixed1) // PostScript limitation.
- adjustValue = fixed1;
-
- return(adjustValue);
-
- }//SkiaMiterToPS
-
- //<FF>
- /****************************
- GetPSLineJoin:
-
- Assumes the line join is one of
- the PostScript standard joins and
- returns the correct enumerated value.
-
- Returns -1 if join isn't postscriptable.
-
- *****************************/
- long GetPSLineJoin(gxJoinRecord* theJoin)
- {
- register long psJoin;
-
- if ( theJoin->join != nil )
- psJoin = -1; // PostScript can't do shape join yet.
-
- else if (theJoin->attributes == gxSharpJoin)
- if (theJoin->miter != 0)
- psJoin = eMiterJoin;
- else
- psJoin = eBevelJoin;
-
- else if (theJoin->attributes == gxCurveJoin)
- psJoin = eRoundJoin;
-
- return(psJoin);
-
- }//GetPSLineJoin
-
-
- //<FF>
- /****************************
-
- DisposeGstateItems:
-
- Function disposes of all graphics
- objects owned by a graphics state
- record.
-
- Important to note: the pointer
- to the graphics state could be
- pointing into an unlocked handle.
- So don't assume moving memory
- will preserve it.
-
- *****************************/
- void DisposeGstateItems(TGstate *pGstate)
- {
- gxTransform theTransform;
- gxInk theInk;
- gxTag theHalftoneTag;
- gxColorProfile theProfile;
-
- /** get the stuff before making any gx gra[hics calls in case they move memory **/
-
- theTransform = pGstate->theTransform;
- theInk = pGstate->theInk;
- theHalftoneTag = pGstate->halftoneTag;
- theProfile = pGstate->currProfile;
-
- GXDisposeTransform(theTransform);
- GXDisposeInk(theInk);
-
- if (theHalftoneTag != nil)
- GXDisposeTag(theHalftoneTag);
-
- if (theProfile != nil)
- GXDisposeColorProfile(theProfile);
-
- }//DisposeGstateItems
-
-
- //<FF>
- /***************************
-
- Imaging engine wrapper for sending
- the buffer data message. This wrapper
- is called to ensure that the RDUtilities
- buffer is flushed before data is sent
- directly to BufferData.
-
- ****************************/
- OSErr PSIEBufferData(TIEGlobalsHdl hIEGlobals, unsigned char *data, long length, long flags)
- {
- OSErr status;
-
- status = RDFlushBuffer((*hIEGlobals)->rdMap);
- nrequire(status, failed_rdFlush);
-
- status = (*hIEGlobals)->psDevice->BufferData((char*)data, length, flags);
- ncheck(status);
-
- failed_rdFlush:
- return(status);
-
- }
-
-
-
-
-
- //<FF>
- /**************************
-
- PSTextToPath:
-
- Converts a text/layout/glyph shape
- into a picture full o'paths. One for
- each glyph. This helps avoid limitchecks.
-
- ****************************/
- OSErr PSTextToPaths(gxShape theShape)
- {
- OSErr status;
- long i, count;
- gxShape aShape;
-
- status = ShUDissectGlyphs(theShape, false); // false for per glyph rather than per style.
- if (status == shape_already_in_simple_form) { // This means ShUDissect did nothing
-
- /* We always want a picture, even if there is only one glyph */
- GXSetShapeType(theShape, gxPictureType);
- status = GXGetGraphicsError(nil);
-
- }//end if
- nrequire(status, failed_dissect);
-
- /** Now convert each element to a path **/
-
- count = GXGetPictureParts(theShape, 1, gxSelectToEnd, nil, nil, nil, nil);
-
- for (i = 1; i <= count; ++i) {
-
- GXGetPictureParts(theShape, i, 1, &aShape, nil, nil, nil);
-
- status = TextToUnhintedPath(aShape);
- nrequire(status, failed_SetShapeType);
-
- }//end for
-
- failed_SetShapeType:
- failed_dissect:
-
- return(status);
-
- }//PSTextToPaths
-
-
- /******************************************
-
- GetColorProfileSize
-
- if size != nil, data size returned in here.
-
- Function returns the size of the profile.
-
- If the profile is not a ColorSync version 1
- return zero, this will make the rest of the code
- think it is zero length and not do matching.
- What else can we do?????? For more information
- Contact Steve Swen.
-
- Wouldn't need this wrapper if ColorSync 2.0
- were going to be backward compatible.
-
- *******************************************/
- long GetColorProfileSize(gxColorProfile theProfile, long *profileVersion)
- {
- CMProfile *profileData;
- long version;
- long size;
-
- GXLockColorProfile(theProfile);
- profileData = (CMProfile*)GXGetColorProfileStructure(theProfile, &size);
-
- /** Treat non version 1 profiles the same as zero length profiles - no matching **/
- if ( (size > 0) ) {
-
- version = profileData->header.applProfileVersion;
- if (version != cmCS1ProfileVersion) {
-
- #if DEBUGLEVEL > 1
- /* Steve Swen is a goof */
- dprintf(trace, "Document contained profile version: %X; disabling matching for this profile", version);
- #endif
- size = 0;
-
- }//end if
-
- } else {
-
- version = cmCS1ProfileVersion;
-
- }//end if
-
- GXUnlockColorProfile(theProfile);
-
- if (profileVersion != nil)
- *profileVersion = version;
-
- return(size);
-
- }//GetColorProfileVersion
-
-
-